<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        工资:<input type="text" v-model="salary" />{{
        salary }}</span>
        <br />
        奖金:<input type="text" v-model="bonus" /><span
        v-text="bonus">
        <br />
        <span>到手:{{ cTotalMoney }}</span>
        <button @click="hDobule">工资加倍</button>
    </div>
    
    <script>
        class Vue {
          constructor (options) {
            options.beforeCreate && options.beforeCreate() // 执行生命周期函数
            this.$el = document.querySelector(options.el)
            this.$options = options
            this._init()
            this.fn(options)
            options.created && options.created()
          }
          fn (option) {
            new Observer(option)
          }
        }
        Vue.prototype._init = function () {
            Vue.prototype.$data = this.$options.data
            const vm = this
            initData(vm, this.$options.data)
        }

        function initData (vm, data) {
          const keys = Object.keys(data)
          keys.forEach(key => {
            vm[key] = data[key]
          })
        }

        class Observer {
          constructor (value) {
            if (Array.isArray(value)) {
              // TODO 监听数组操作
            } else {
              this.walk(value)
            }
          }
          walk (obj) {
            const keys = Object.keys(obj)
            for (let i = 0, l = keys.length; i < l; i++) {
              defineReactive(obj, keys[i])
            }
          }
        }

        function defineReactive (obj, key, val) {
        //   console.log(obj,key,val);
          if (arguments.length === 2) {
            val = obj[key]
          }
          if(typeof val === 'object'){
            new Observer(val)
          }
          Object.defineProperty(obj, key, {
            get () {
              console.log('getter')
              return val
            },
            set (newVal) {
              console.log('setting')
              if (val === newVal) return
              val = newVal
            }
          })

        }

        var vm = new Vue({
          el: "#app",
          data: {
            salary: 10000,
            bonus: 50000,
            a: 100
          },
          computed: {
            cTotalMoney() {
              console.info("computed.....");
              return +this.salary + +this.bonus;
            }
          },
          methods: {
            hDobule() {
              this.salary *= 2;
            }
          }
        });
        console.log(vm);
    </script>
</body>
</html>